{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# EDA Case Study: House Price"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Task Description\n",
    "House Prices is a classical Kaggle competition. The task is to predicts final price of each house. For more detail, refer to https://www.kaggle.com/c/house-prices-advanced-regression-techniques/.\n",
    "\n",
    "### Goal of this notebook\n",
    "As it is a famous competition, there exists lots of excelent analysis on how to do eda and how to build model for this task. See https://www.kaggle.com/khandelwallaksya/house-prices-eda for a reference. In this notebook, we will show how dataprep.eda can simply the eda process using a few lines of code.\n",
    "\n",
    "In conclusion:\n",
    "* **Understand the problem**. We'll look at each variable and do a philosophical analysis about their meaning and importance for this problem.\n",
    "* **Univariable study**. We'll just focus on the dependent variable ('SalePrice') and try to know a little bit more about it.\n",
    "* **Multivariate study**. We'll try to understand how the dependent variable and independent variables relate.\n",
    "* **Basic cleaning**. We'll clean the dataset and handle the missing data, outliers and categorical variables."
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Import libraries"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "from dataprep.eda import plot\n",
    "from dataprep.eda import plot_correlation\n",
    "from dataprep.eda import plot_missing\n",
    "from dataprep.datasets import load_dataset\n",
    "\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "sns.set(style=\"whitegrid\", color_codes=True)\n",
    "sns.set(font_scale=1)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Load data"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "houses = load_dataset(\"house_prices_train\")\n",
    "houses.head()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "houses_test = load_dataset(\"house_prices_test\")\n",
    "houses_test.head()"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "houses.shape"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "There are total 1460 tuples, each tuple contains 80 features and 1 target value."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "houses_test.shape"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Variable identification"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Overview of the data\n",
    "We could get the following information:\n",
    "* **Variable**-Variable name\n",
    "* **Type**-There are 43 categorical columns and 38 numerical columns.\n",
    "* **Missing value**-How many missing values each column contains. For instance, Fence contains 80.8% * 1460 = 1180 missing tuples. Usually, some model does not allow the input data contains missing value such as SVM, we have to clean the data before we utilize it.\n",
    "* **Target Value**-The distribution of target value (SalePrice). According to the distribution of the target value, we could get the information that the target value is numerical and the distribution of the target value conforms to the norm distribution. Thus, we are not confronted with imbalanced classes problem. It is really great.\n",
    "* **Guess**-According to the columns' name, we reckon GrLivArea, YearBuilt and OverallQual are likely to be correlated to the target value (SalePrice)."
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Correlation in data"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses, \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses, \"SalePrice\", value_range=[0.5, 1])"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "OverallQual, GrLivArea, GarageCars, GarageArea, TotalBsmtSF, 1stFlrSF, FullBath, TotRmsAbvGrd, YearBuilt, YearRemodAdd have more than 0.5 Pearson correlation with SalePrice.\n",
    "\n",
    "OverallQual, GrLivArea, GarageCars, YearBuilt, GarageArea, FullBath, TotalBsmtSF, GarageYrBlt, 1stFlrSF, YearRemodAdd, TotRmsAbvGrd and Fireplaces have more than 0.5 Spearman correlation with SalePrice. \n",
    "\n",
    "OverallQual, GarageCars, GrLivArea and FullBath have more than 0.5 KendallTau correlation with SalePrice.\n",
    "\n",
    "EnclosedPorch and KitchenAbvGr have little negative correlation with target variable.\n",
    "\n",
    "These can prove to be important features to predict SalePrice."
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Heatmap"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### In summary\n",
    "In my opinion, this heatmap is the best way to get a quick overview of features' relationships.\n",
    "\n",
    "At first sight, there are two red colored squares that get my attention. The first one refers to the 'TotalBsmtSF' and '1stFlrSF' variables, and the second one refers to the 'GarageX' variables. Both cases show how significant the correlation is between these variables. Actually, this correlation is so strong that it can indicate a situation of multicollinearity. If we think about these variables, we can conclude that they give almost the same information so multicollinearity really occurs. Heatmaps are great to detect this kind of situations and in problems dominated by feature selection, like ours, they are an essential tool.\n",
    "\n",
    "Another thing that got my attention was the 'SalePrice' correlations. We can see our well-known 'GrLivArea', 'TotalBsmtSF', and 'OverallQual', but we can also see many other variables that should be taken into account. That's what we will do next."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses[[\"SalePrice\",\"OverallQual\",\"GrLivArea\",\"GarageCars\",\n",
    "                  \"GarageArea\",\"GarageYrBlt\",\"TotalBsmtSF\",\"1stFlrSF\",\"FullBath\",\n",
    "                  \"TotRmsAbvGrd\",\"YearBuilt\",\"YearRemodAdd\"]])"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "As we saw above there are few feature which shows high multicollinearity from heatmap. Lets focus on red squares on diagonal line and few on the sides.\n",
    "\n",
    "SalePrice and OverallQual\n",
    "\n",
    "GarageArea and GarageCars\n",
    "\n",
    "TotalBsmtSF and 1stFlrSF\n",
    "\n",
    "GrLiveArea and TotRmsAbvGrd\n",
    "\n",
    "YearBulit and GarageYrBlt\n",
    "\n",
    "We have to create a single feature from them before we use them as predictors."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses, value_range=[0.5, 1])"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses, k=30)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "**Attribute Pair\tCorrelation**\n",
    "\n",
    "7\t(GarageArea, GarageCars)\t0.882475\n",
    "\n",
    "11\t(GarageYrBlt, YearBuilt)\t0.825667\n",
    "\n",
    "15\t(GrLivArea, TotRmsAbvGrd)\t0.825489\n",
    "\n",
    "18\t(1stFlrSF, TotalBsmtSF)\t0.819530\n",
    "\n",
    "19\t(2ndFlrSF, GrLivArea)\t0.687501\n",
    "\n",
    "9\t(BedroomAbvGr, TotRmsAbvGrd)\t0.676620\n",
    "\n",
    "0\t(BsmtFinSF1, BsmtFullBath)\t0.649212\n",
    "\n",
    "2\t(GarageYrBlt, YearRemodAdd)\t0.642277\n",
    "\n",
    "24\t(FullBath, GrLivArea)\t0.630012\n",
    "\n",
    "8\t(2ndFlrSF, TotRmsAbvGrd)\t0.616423\n",
    "\n",
    "1\t(2ndFlrSF, HalfBath)\t0.609707\n",
    "\n",
    "4\t(GarageCars, OverallQual)\t0.600671\n",
    "\n",
    "16\t(GrLivArea, OverallQual)\t0.593007\n",
    "\n",
    "23\t(YearBuilt, YearRemodAdd)\t0.592855\n",
    "\n",
    "22\t(GarageCars, GarageYrBlt)\t0.588920\n",
    "\n",
    "12\t(OverallQual, YearBuilt)\t0.572323\n",
    "\n",
    "5\t(1stFlrSF, GrLivArea)\t0.566024\n",
    "\n",
    "25\t(GarageArea, GarageYrBlt)\t0.564567\n",
    "\n",
    "6\t(GarageArea, OverallQual)\t0.562022\n",
    "\n",
    "17\t(FullBath, TotRmsAbvGrd)\t0.554784\n",
    "\n",
    "13\t(OverallQual, YearRemodAdd)\t0.550684\n",
    "\n",
    "14\t(FullBath, OverallQual)\t0.550600\n",
    "\n",
    "3\t(GarageYrBlt, OverallQual)\t0.547766\n",
    "\n",
    "10\t(GarageCars, YearBuilt)\t0.537850\n",
    "\n",
    "27\t(OverallQual, TotalBsmtSF)\t0.537808\n",
    "\n",
    "20\t(BsmtFinSF1, TotalBsmtSF)\t0.522396\n",
    "\n",
    "21\t(BedroomAbvGr, GrLivArea)\t0.521270\n",
    "\n",
    "26\t(2ndFlrSF, BedroomAbvGr)\t0.502901\n",
    "\n",
    "This shows multicollinearity. In regression, \"multicollinearity\" refers to features that are correlated with other features. Multicollinearity occurs when your model includes multiple factors that are correlated not just to your target variable, but also to each other.\n",
    "\n",
    "Problem:\n",
    "\n",
    "Multicollinearity increases the standard errors of the coefficients. That means, multicollinearity makes some variables statistically insignificant when they should be significant.\n",
    "\n",
    "To avoid this we can do 3 things:\n",
    "\n",
    "Completely remove those variables\n",
    "Make new feature by adding them or by some other operation.\n",
    "Use PCA, which will reduce feature set to small number of non-collinear features.\n",
    "Reference:http://blog.minitab.com/blog/understanding-statistics/handling-multicollinearity-in-regression-analysis"
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Univariate Analysis\n",
    "How 1 single variable is distributed in numeric range. What is statistical summary of it. Is it positively skewed or negatively."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Pivotal Features"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_correlation(houses, \"OverallQual\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"OverallQual\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"GarageCars\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"Fireplaces\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"GrLivArea\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"TotalBsmtSF\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot(houses, \"YearBuilt\", \"SalePrice\")"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### In summary\n",
    "Based on the above analysis, we can conclude that:\n",
    "\n",
    "'GrLivArea' and 'TotalBsmtSF' seem to be linearly related with 'SalePrice'. Both relationships are positive, which means that as one variable increases, the other also increases. In the case of 'TotalBsmtSF', we can see that the slope of the linear relationship is particularly high.\n",
    "'OverallQual' and 'YearBuilt' also seem to be related with 'SalePrice'. The relationship seems to be stronger in the case of 'OverallQual', where the box plot shows how sales prices increase with the overall quality.\n",
    "We just analysed four variables, but there are many other that we should analyse. The trick here seems to be the choice of the right features (feature selection) and not the definition of complex relationships between them (feature engineering).\n",
    "\n",
    "That said, let's separate the wheat from the chaff."
   ],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Missing Value Imputation\n",
    "Missing values in the training data set can affect prediction or classification of a model negatively.\n",
    "\n",
    "Also some machine learning algorithms can't accept missing data eg. SVM, Neural Network.\n",
    "\n",
    "But filling missing values with mean/median/mode or using another predictive model to predict missing values is also a prediction which may not be 100% accurate, instead you can use models like Decision Trees and Random Forest which handle missing values very well.\n",
    "\n",
    "Some of this part is based on this kernel: https://www.kaggle.com/bisaria/house-prices-advanced-regression-techniques/handling-missing-data"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "plot_missing(houses)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# plot_missing(houses, \"BsmtQual\")\n",
    "basement_cols=['BsmtQual','BsmtCond','BsmtExposure','BsmtFinType1','BsmtFinType2','BsmtFinSF1','BsmtFinSF2']\n",
    "houses[basement_cols][houses['BsmtQual'].isnull()==True]"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "All categorical variables contains NAN whereas continuous ones have 0. So that means there is no basement for those houses. we can replace it with 'None'."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "for col in basement_cols:\n",
    "    if 'FinSF'not in col:\n",
    "        houses[col] = houses[col].fillna('None')"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "# plot_missing(houses, \"FireplaceQu\")\n",
    "houses[\"FireplaceQu\"] = houses[\"FireplaceQu\"].fillna('None')\n",
    "pd.crosstab(houses.Fireplaces, houses.FireplaceQu)"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "garage_cols=['GarageType','GarageQual','GarageCond','GarageYrBlt','GarageFinish','GarageCars','GarageArea']\n",
    "houses[garage_cols][houses['GarageType'].isnull()==True]"
   ],
   "outputs": [],
   "metadata": {}
  },
  {
   "cell_type": "markdown",
   "source": [
    "All garage related features are missing values in same rows. that means we can replace categorical variables with None and continuous ones with 0."
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "source": [
    "for col in garage_cols:\n",
    "    if houses[col].dtype==np.object:\n",
    "        houses[col] = houses[col].fillna('None')\n",
    "    else:\n",
    "        houses[col] = houses[col].fillna(0)"
   ],
   "outputs": [],
   "metadata": {}
  }
 ],
 "metadata": {
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}